use crate::stdlib::asm::{inb, outb};

#[derive(Copy, Clone)]
pub enum SerialPort {
    COM1 = 0x3f8,
    _COM2 = 0x2f8,
    _COM3 = 0x3e8,
    _COM4 = 0x2e8,
}

impl Default for SerialPort {
    fn default() -> Self {
        SerialPort::COM1
    }
}

pub fn init_serial_with_port(port: SerialPort) {
    let port = port as u16;
    unsafe {
        outb(port + 1, 0x00); // Disable all interrupts
        outb(port + 3, 0x80); // Enable DLAB (set baud rate divisor)
        outb(port + 0, 0x03); // Set divisor to 3 (lo byte) 38400 baud
        outb(port + 1, 0x00); //                  (hi byte)
        outb(port + 3, 0x03); // 8 bits, no parity, one stop bit
        outb(port + 2, 0xC7); // Enable FIFO, clear them, with 14-byte threshold
        outb(port + 4, 0x0B); // IRQs enabled, RTS/DSR set
    }
}

pub fn write_serial_with_port(port: SerialPort, a: u8) {
    let port = port as u16;
    unsafe {
        while inb(port + 5) & 0x20 == 0 {
            // wait...
        }
        outb(port, a);
    }
}
